package edu.zju.gis.dbfg.queryserver.service.impl;

import edu.zju.gis.dbfg.queryserver.model.SearchResult;
import edu.zju.gis.dbfg.queryserver.service.MapServiceService;
import edu.zju.gis.dbfg.queryserver.tool.RestElasticSearchHelper;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import java.util.*;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;


@Slf4j
@Service
public class MapServiceServiceImpl implements MapServiceService {

    @Autowired
    private RestElasticSearchHelper helper;

    @Cacheable(value="search",sync=true)
    @Override
    public SearchResult search(String requestBody) {
        JSONObject params = new JSONObject(requestBody);
        String keyword = params.optString("keyword");
        String publisherID = "";
        String publisherRole = "user";
        if(params.has("publisherRole"))
            publisherRole = params.optString("publisherRole");
        if (params.has("publisherID"))
            publisherID = params.optString("publisherID");
        QueryBuilder builder = QueryBuilders.boolQuery()
                .must(QueryBuilders.matchQuery("keyword",keyword))
                .must(QueryBuilders.matchQuery("publisher_id",publisherID))
                .must(QueryBuilders.matchQuery("publisher_role",publisherRole));
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().query(builder);
        SearchRequest request = new SearchRequest().indices("mapservice").source(searchSourceBuilder);
        try {
            SearchResponse response = helper.search(request);
            return response2Result(1,2000,response);
        }catch (Exception ex)
        {
            return null;
        }

    }

    public SearchResult response2Result(Integer page, Integer pagecap, SearchResponse response) {
        SearchResult result = new SearchResult();
//        result.setCurpage(page);
//        result.setPagecount(pagecap);
        result.setCurresult(response.getHits().getHits().length);
        result.setTotal(response.getHits().getTotalHits().value);
        result.setTime(response.getTook().getSecondsFrac());
        SearchHits hits = response.getHits();
        List<Map<String, Object>> features = new ArrayList<>();
        for (SearchHit hit : hits) {
            Map<String, Object> item = hit.getSourceAsMap();
            features.add(item);
        }
        if (pagecap == null)
            pagecap = 10;
        if (pagecap < features.size())
            features = new ArrayList<>(features.subList(0, pagecap));
        result.setFeatures(features);
        return result;
    }

}
